package com.job;

import java.io.Serializable;
import java.lang.reflect.Method;
import org.quartz.*;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * @author HuangSuip
 */
public abstract class BaseCronTrigger extends CronTriggerFactoryBean implements Serializable {

    public BaseCronTrigger() {
        super();
        init();
    }

    public void init() {
/*        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(getMyTargetObject().getClass());
        factoryBean.setDurability(true);
        factoryBean.setRequestsRecovery(true);
        factoryBean.setGroup(getGroupName());
        Map<String, String> map = new HashMap<>();
        map.put("targetObject", getName());
        map.put("targetMethod", "execute");
        factoryBean.setJobDataAsMap(map);*/
        JobDetail jobdetail = JobBuilder.newJob(getMyTargetObject()).build();
        this.setName(this.getClass().getSimpleName());
        this.setCronExpression(this.getMyCronExpression());
        this.setJobDetail(jobdetail);
    }

    public abstract String getMyCronExpression();

    public abstract String getGroupName();

    public abstract String getName();

    public abstract Class<? extends Job> getMyTargetObject();

}

class InvokingJobDetailDetailFactory extends QuartzJobBean {

    // 计划任务所在类
    private String targetObject;

    // 具体需要执行的计划任务
    private String targetMethod;

    private ApplicationContext ctx;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        try {
            Object otargetObject = ctx.getBean(targetObject);
            Method m = otargetObject.getClass().getMethod(targetMethod);
            m.invoke(otargetObject);
        } catch (Exception e) {
            throw new JobExecutionException(e);
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.ctx = applicationContext;
    }

    public void setTargetObject(String targetObject) {
        this.targetObject = targetObject;
    }

    public void setTargetMethod(String targetMethod) {
        this.targetMethod = targetMethod;
    }
}
